using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using DevExpress.Xpo;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;
using DevExpress.Data.Filtering;
using DevExpress.Utils;
using ChuanPlus.DAO;
namespace ChuanPlus.FormControl
{
    public partial class ControlPurOrder : DevExpress.XtraEditors.XtraUserControl
    {
        List<PurchaseProduct> lstOrderDetails = new List<PurchaseProduct>();
        List<Customer> lstCustomer = null;
        List<PreviousPrice> lst = null;
        Users currentUser = null;
        public ControlPurOrder(Users currentUser)
        {
            InitializeComponent();
            gridBottom.DataSource = lstOrderDetails;
            // initial customer list and bind to control
            lstCustomer = CustomerDAO.GetAllCustomer();            
            comboCustomer.Properties.Items.AddRange(lstCustomer);                      
            // initial users list
            comboSalesRep.Properties.Items.AddRange(xpColUsers);
            textOrderID.Focus();
            this.currentUser = currentUser;
            textOrderID.Text = OrderDAO.GenerateId().ToString();
        }
        
        private void gridView1_DoubleClick(object sender, EventArgs e)
        {
            // Checks whether an end-used has double clicked the row indicator.
            GridHitInfo hi = gridView1.CalcHitInfo(gridTop.PointToClient(MousePosition));
            if (!hi.InRow) return;
            // Retrieves the persistent object that corresponds to the currently focused grid row.
            int DSRowIndex = gridView1.Columns.View.GetDataSourceRowIndex(gridView1.FocusedRowHandle);
            Stock currentStock = xpColItemList[DSRowIndex] as Stock;
            if (currentStock.warehouseID.warehouseId == 2)  // do not get product from stock, just get from office
                return;
            // check if user select same distributor in one PO
            if (lstOrderDetails.Count > 0)
            {
                string disName = currentStock.ID.DistributorID.DistributorName;
                if (disName != lstOrderDetails[0].Distributor)
                {
                    lblMessage.Text = "Current distributor in PO is " + lstOrderDetails[0].Distributor;
                    lblMessage.Text += ", Cannot add " + disName + " to PO";
                    return;
                }
                else
                    lblMessage.Text = "";
            }
            PurchaseProduct p = new PurchaseProduct(currentStock, currentStock.ID.ItemCode, currentStock.ID.Description, 0.0, 1, checkVAT.Checked,currentStock.ID.DistributorID.DistributorName);
            if(lstOrderDetails.Contains(p))     // do not add to list if product is added
                return;
            
            lstOrderDetails.Add(p);            
            gridBottom.RefreshDataSource();
            
        }      

        private void gridView2_CellValueChanged(object sender, CellValueChangedEventArgs e)
        {
           int DSRowIndex = gridView2.Columns.View.GetDataSourceRowIndex(e.RowHandle);
            if(e.Column.FieldName == "Quantity")
                lstOrderDetails[DSRowIndex].qty = Double.Parse(e.Value.ToString());
            else if (e.Column.FieldName == "UnitPrice")
                lstOrderDetails[DSRowIndex].UnitPrice = Double.Parse(e.Value.ToString());
            lstOrderDetails[DSRowIndex].RefreshTotal();
           gridBottom.RefreshDataSource();     
        }    

        //protected void gridView2_DoubleClick(object sender, EventArgs e)
        //{
        //    // Checks whether an end-used has double clicked the row indicator.
        //    GridHitInfo hi = gridView2.CalcHitInfo(gridBottom.PointToClient(MousePosition));
        //    if (!hi.InRow) return;
        //    // Retrieves the persistent object that corresponds to the currently focused grid row.
        //    int DSRowIndex = gridView2.Columns.View.GetDataSourceRowIndex(gridView2.FocusedRowHandle);
        //    lstOrderDetails.RemoveAt(DSRowIndex);     // do not add to list if product is added      
        //    gridBottom.RefreshDataSource();
        //}

        private void textFilter_EditValueChanged(object sender, EventArgs e)
        {
            
            CriteriaOperator opeLeft = new BinaryOperator(new OperandProperty("ID.ItemCode"),new OperandValue("%" + textFilter.Text + "%"),BinaryOperatorType.Like);            
            CriteriaOperator opeRight = new BinaryOperator(new OperandProperty("ID.Description"),new OperandValue("%" + textFilter.Text + "%"),BinaryOperatorType.Like);
            CriteriaOperator filter = new GroupOperator(GroupOperatorType.Or,new CriteriaOperator[2]{opeLeft, opeRight});            
            xpColItemList.Filter = filter;
        }

        private void comboCustomer_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboCustomer.SelectedIndex != -1)
            {
                Customer cus = comboCustomer.SelectedItem as Customer;
                memoAddress.Text = cus.CustomerAdd;
                textPhone.Text = cus.CustomerPhone;
                textFax.Text = cus.CustomerFax;
                textCredit.Text = cus.Credit.ToString();
                textCreditLimit.Text = cus.CreditLimit.ToString();
                comboPayment.Text = cus.PaymentTerm;
            }
        }      

        private void checkVAT_CheckedChanged(object sender, EventArgs e)
        {
            bool takeRebInvoice = checkVAT.Checked;
            for (int i = 0; i < lstOrderDetails.Count; i++)
            {
                lstOrderDetails[i].TakeRedInvoice = takeRebInvoice;
            }
            gridBottom.RefreshDataSource();
        }

        private void buttonPurchase_Click(object sender, EventArgs e)
        {
            
            if (!validation()) return;
            DialogResult result =  MessageBox.Show("Are you sure want to create a new Purchase Order?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
            if (result.ToString() == "Yes")
            {
                // get summary value from footer row
                double total = Convert.ToDouble(gridView2.Columns["Total"].SummaryItem.SummaryValue);

                Customer cus = comboCustomer.SelectedItem as Customer;
                string sCommission = textCommission.Text.Replace(",","");
                double custComission = Double.Parse(sCommission);
                // total after substract customer comission
                total = total - custComission;
                // change code when release
                //Order order = new Order(Session.DefaultSession, textOrderID.Text, cus, DateTime.Now, comboPayment.SelectedText, DateTime.Now, user, "", "", 0, total, user, null, true);
                Order order = new Order(Session.DefaultSession, textOrderID.Text, cus, dateOrder.DateTime, comboPayment.Text, dateDelivery.DateTime,comboSalesRep.SelectedItem as Users, "", memoRemark.Text,custComission , total, currentUser, null, "H");
                for (int i = 0; i < lstOrderDetails.Count; i++)
                {
                    PurchaseProduct p = lstOrderDetails[i];
                    order.OrderDetails.Add(new OrderDetails(p.stock, p.qty, p.UnitPrice, p.Tax));
                }
                order.Save();
                Reset();
            }
        }
#region Validation
        private bool validation()
        {
            
            if (textOrderID.Text == "")
            {
                MessageBox.Show("Please enter Purchase No","Message",MessageBoxButtons.OK,MessageBoxIcon.Error); textOrderID.Focus(); return false;
            }
            if (comboCustomer.SelectedItem == null)
            {
                MessageBox.Show("Please select a customer", "Message", MessageBoxButtons.OK, MessageBoxIcon.Error); comboCustomer.Focus(); return false; 
            }
            if (dateOrder.Text =="")
            {
                MessageBox.Show("Please pick purchase date", "Message", MessageBoxButtons.OK, MessageBoxIcon.Error); dateOrder.Focus(); return false;
            }
            if (comboPayment.Text == "")
            {
                MessageBox.Show("Please select a Term of payment", "Message", MessageBoxButtons.OK, MessageBoxIcon.Error); comboPayment.Focus(); return false;
            }
            if (dateDelivery.Text == "")
            {
                MessageBox.Show("Please pick delivery date", "Message", MessageBoxButtons.OK, MessageBoxIcon.Error); dateDelivery.Focus(); return false;
            }
            if (comboSalesRep.Text == "")
            {
                MessageBox.Show("Please select a Sale rep", "Message", MessageBoxButtons.OK, MessageBoxIcon.Error); comboSalesRep.Focus(); return false;
            }
            if (lstOrderDetails.Count <= 0) // validate purchase item in PO
            {
                MessageBox.Show("Please select purchase item", "Message", MessageBoxButtons.OK, MessageBoxIcon.Error); return false;
            }            
            if (!priceValidation())
                return false;
            double total = Convert.ToDouble(gridView2.Columns["Total"].SummaryItem.SummaryValue);
            if (total < double.Parse(textCommission.Text))
            {
                MessageBox.Show("Customer comission greater than total of PO", "Message", MessageBoxButtons.OK, MessageBoxIcon.Error); return false;
            }
            return true;
        }
        private void textOrderID_Validating(object sender, CancelEventArgs e)
        {
            Order o = OrderDAO.GetOrderByID(textOrderID.Text);
            if (o != null)
            {
                e.Cancel = true;
                textOrderID.ErrorText = "This Purchase Order ID is used";
            }
        }
        private bool priceValidation()
        {
            foreach (PurchaseProduct item in lstOrderDetails)
            {
                if (item.UnitPrice == 0)
                {
                    MessageBox.Show("Please enter unit price for purchase item","Message",MessageBoxButtons.OK,MessageBoxIcon.Error);
                    return false;
                }
            }
            return true;
        }

        private void dateDelivery_Properties_Validating(object sender, CancelEventArgs e)
        {
            DateTime deliveryDate = dateDelivery.DateTime;
            DateTime orderDate = dateOrder.DateTime;
            if (DateTime.Compare(deliveryDate, orderDate) == -1)
            {
                e.Cancel = true;
                dateDelivery.ErrorText = "Delivery  Date should greater or equal to Order Date";
            }
        }
        private void dateOrder_Properties_Validating(object sender, CancelEventArgs e)
        {
            DateTime deliveryDate = dateDelivery.DateTime;
            DateTime orderDate = dateOrder.DateTime;
            if (dateDelivery.Text != "" && DateTime.Compare(deliveryDate, orderDate) == -1)
            {
                e.Cancel = true;
                dateOrder.ErrorText = "Delivery Date should greater or equal to Order Date";
            }
        }
        private void textOrderID_Properties_Validating(object sender, CancelEventArgs e)
        {
            if (textOrderID.EditValue == null)
            {
                e.Cancel = true;
            }
        }

        private void comboCustomer_Properties_Validating(object sender, CancelEventArgs e)
        {
            if (comboCustomer.EditValue == null)
            {
                e.Cancel = true;
            }
        }
        private void gridView2_ValidatingEditor(object sender, DevExpress.XtraEditors.Controls.BaseContainerValidateEditorEventArgs e)
        {

            if (gridView2.FocusedColumn.FieldName == "qty")
            {

                int DSRowIndex = gridView2.Columns.View.GetDataSourceRowIndex(gridView2.FocusedRowHandle);
                Stock s = lstOrderDetails[DSRowIndex].stock;
                double instock = s.QtyBalance;
                //Get the currently edited value
                double qty = Convert.ToDouble(e.Value);
                //Specify validation criteria
                if (qty < 0)
                {
                    e.Valid = false;
                    e.ErrorText = "Enter a positive value";
                }
                if (qty > instock)
                {
                    e.Valid = false;
                    e.ErrorText = "Reduce the quantity (" + instock + " is maximum)";
                }
            }
            if (gridView2.FocusedColumn.FieldName == "UnitPrice")
            {
                if (Convert.ToDouble(e.Value) < 0)
                {
                    e.Valid = false;
                    e.ErrorText = "Enter a positive value";
                }
            }
        }
        private void comboCustomer_Validating(object sender, CancelEventArgs e)
        {
            Customer c = comboCustomer.SelectedItem as Customer;
            if (c == null)
            {
                e.Cancel = true;
                comboCustomer.ErrorText = "Customer " + comboCustomer.Text + " does not exsit";
            }
        }

        private void comboSalesRep_Validating(object sender, CancelEventArgs e)
        {
            Users u = comboSalesRep.SelectedItem as Users;
            if (u == null)
            {
                e.Cancel = true;
                comboSalesRep.ErrorText = "Salesman " + comboSalesRep.Text + " does not exsit";
            }
        }
#endregion

        private void Reset()
        {
            lstOrderDetails.Clear();            
            comboCustomer.SelectedItem = null;
            memoAddress.Text = textPhone.Text = textFax.Text = textCredit.Text = textCreditLimit.Text = "";
            dateOrder.Text = dateDelivery.Text = "";
            comboPayment.Text = "";
            textCommission.Text = "";
            memoRemark.Text = "";
            gridBottom.RefreshDataSource();
            gridTop.RefreshDataSource();
        }

        private void gridView2_KeyDown(object sender, KeyEventArgs e)
        {
             int DSRowIndex = 0;
            if (e.KeyCode == Keys.Delete)
            {
                // Retrieves the persistent object that corresponds to the currently focused grid row.
                int focusedRow = gridView2.FocusedRowHandle;
                if (focusedRow >= 0)
                {
                    DSRowIndex = gridView2.Columns.View.GetDataSourceRowIndex(focusedRow);
                    lstOrderDetails.RemoveAt(DSRowIndex);     // do not add to list if product is added      
                    gridBottom.RefreshDataSource();
                }
            }
        }

        private void toolTipController1_GetActiveObjectInfo(object sender, DevExpress.Utils.ToolTipControllerGetActiveObjectInfoEventArgs e)
        {
            if (e.SelectedControl != gridBottom) return;
            ToolTipControlInfo info = null;
            try
            {
                GridView view = gridBottom.GetViewAt(e.ControlMousePosition) as GridView;
                if (view == null) return;
                GridHitInfo hi = view.CalcHitInfo(e.ControlMousePosition);                
                if (hi.InRowCell)
                {
                    if (hi.Column.FieldName == "UnitPrice" && comboCustomer.SelectedItem != null)
                    {
                        info = GetToolTip(view, hi.RowHandle, hi.Column);
                    }
                }
            }
            finally
            {
                e.Info = info;
                
            }

        }
        private ToolTipControlInfo GetToolTip(GridView view, int rowHandle, DevExpress.XtraGrid.Columns.GridColumn column)
        {
            string content = "";
            string title = "";
            int DSRowIndex = view.GetDataSourceRowIndex(rowHandle);
            PurchaseProduct purPro = lstOrderDetails[DSRowIndex];
            lst = OrderDAO.GetPreviousSalePrice(comboCustomer.Text, purPro.stock.ID.ID); // query db and get previous price for this customer, this product
            foreach (PreviousPrice item in lst)
            {
                content += item.OrderDate.ToString("dd/MM/yyyy") + "\t";
                content += String.Format("{0:n}",item.UnitPrice) + "\n";
            }
            title = comboCustomer.Text + " - " + purPro.description;
            ToolTipControlInfo info = new ToolTipControlInfo(new CellToolTipInfo(rowHandle, column, "cell"),content);
            SuperToolTipSetupArgs args = new SuperToolTipSetupArgs();
            args.Title.Text = title;
            args.Contents.Text = content;
            SuperToolTip superTooltip = new SuperToolTip();
            superTooltip.Setup(args);
            info.SuperTip = superTooltip;
            return info;
        }

        private void buttonReset_Click(object sender, EventArgs e)
        {
            Reset();
        }

        private void gridView1_RowStyle(object sender, RowStyleEventArgs e)
        {
            int DSRowIndex = gridView1.GetDataSourceRowIndex(e.RowHandle);
            if (DSRowIndex >= 0)
            {
                Stock s = xpColItemList[DSRowIndex] as Stock;
                if (s.warehouseID.warehouseId == 2)
                    e.Appearance.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(224)))), ((int)(((byte)(192)))));
            
            }
        }

        private void textCommission_Validated(object sender, EventArgs e)
        {
            string sText = textCommission.Text;
            if (sText != "")
                textCommission.Text = String.Format("{0:#,#}", Double.Parse(sText));
            else
                textCommission.Text = "0";
        }

        private void textCreditLimit_Validated(object sender, EventArgs e)
        {
            string sText = textCreditLimit.Text;
            if (sText != "")
                textCreditLimit.Text = string.Format("{0:#,#}", Double.Parse(sText));
        }

        private void textCredit_Validated(object sender, EventArgs e)
        {
            string sText = textCredit.Text;
            if (sText != "")
                textCredit.Text = string.Format("{0:#,#}", Double.Parse(sText));
        }

        


         

       

        

    }
    public class PurchaseProduct
    {
        private Stock _Stock;
        public Stock stock
        {
            get { return _Stock; }
            set { _Stock = value; }
        }
        private string _ItemCode;
        public string ItemCode
        {
            get { return _ItemCode; }
            set { _ItemCode = value; }
        }
        private string _Description;
        public string description
        {
            get { return _Description; }
            set { _Description = value; }
        }
        private double _UnitPrice;
        public double UnitPrice
        {
            get { return _UnitPrice; }
            set {
                _UnitPrice = value;
                _total = qty * UnitPrice;
                }
        }
        private double _Qty;
        public double qty
        {
            get { return _Qty; }
            set { 
                _Qty = value;
                _total = qty * UnitPrice;               
            }
        }
        private bool _TakeRedInvoice;
        public bool TakeRedInvoice
        {
            get { return _TakeRedInvoice; }
            set 
            {
                _TakeRedInvoice = value;
                RefreshTotal();               
            }
        }
        private double _Tax;
        public double Tax
        {
            get { return _Tax; }
            set { _Tax = value; }
        }
        private double _total;
        public double Total
        {
            get { return _total; }
            set { _total = value; }
        }
        private string _Distributor;
        public string Distributor
        {
            get { return _Distributor; }
            set { _Distributor = value; }
        }
        public override bool Equals(Object b)
        {
            bool result = true;
            if (b == null) result = false;
            try
            {
                PurchaseProduct p = (PurchaseProduct)b;
                if (p.stock.ID.ID == this.stock.ID.ID)
                    result = true;
                else
                    result = false;
            }
            catch
            {  
                result = false;
            }
            return result;
        }
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
        /// <summary>
        /// Initializes a new instance of the PurchaseProduct class.
        /// </summary>
        /// <param name="product"></param>
        /// <param name="itemCode"></param>
        /// <param name="description"></param>
        /// <param name="unitPrice"></param>
        /// <param name="qty"></param>   
        /// <param name="Distributor"></param>
        public PurchaseProduct(Stock stock, string itemCode, string description, double unitPrice, double qty,bool TakeRedInvoice, string Distributor)
        {
            _Stock = stock;
            _ItemCode = itemCode;
            _Description = description;
            _UnitPrice = unitPrice;
            this.qty = qty;
            this.TakeRedInvoice = TakeRedInvoice;
            this.Distributor = Distributor;
        }
        public void RefreshTotal()
        {
            if (TakeRedInvoice)
            {
                Tax = (_total * stock.ID.Tax) / 100;
                _total = _total + Tax;
            }
            else
            {
                _total = _total - Tax;
                _Tax = 0;
            }
        }
    }
}
